﻿using Mapster;
using Zhp.Common.Helper;
using Zhp.Common.WebApp;
using Zhp.Entity.Chat;
using Zhp.Entity.SysEnum;
using Zhp.IService.Chat;
using Zhp.IService.Common;
using Zhp.Model.Chat;
using Zhp.Model.Common;
using Zhp.Service.Base;
using Zhp.SqlSugar.Repository;

namespace Zhp.Service.Chat
{
    public class ChatMessageService : BaseService<ChatMessage>, IChatMessageService
    {
        IFileService _fileService;
        IBaseRepository<ChatFriend> _chatFriendRep;
        IBaseRepository<ChatUser> _chatUserRep;
        IBaseRepository<ChatContent> _chatContentRep;
        public ChatMessageService(ICurrentUser currentUser, IBaseRepository<ChatMessage> rep, IFileService fileService, IBaseRepository<ChatFriend> chatFriendRep, IBaseRepository<ChatUser> chatUserRep, IBaseRepository<ChatContent> chatContentRep)
        {
            _currentUser = currentUser;
            _rep = rep;
            _fileService = fileService;
            _chatFriendRep = chatFriendRep;
            _chatUserRep = chatUserRep;
            _chatContentRep = chatContentRep;
        }

        public async Task<(List<ChatMessageModel>, bool)> GetChatMessageListByUserId(QueryChatMessage query)
        {
            //如果查询出来的条数小于这个就没有数据
            int takeCount = 30;
            //更新未读消息
            var noReadList = await _rep.GetListAsync(x => x.BelongId == query.BelongId && x.ReadTime == null);
            foreach (var item in noReadList)
            {
                item.ReadTime = DateTime.Now;
            }
            await _rep.UpdateRangeAsync(noReadList);

            var list = await _rep.AsQueryable().Where(x => x.BelongId == query.BelongId)
                                 .WhereIF(query.TimeStamp != null, x => x.TimeStamp < query.TimeStamp)
                                 .OrderByDescending(x => x.TimeStamp).Take(takeCount).ToListAsync();
            list = list.OrderBy(x => x.TimeStamp).ToList();
            
            var rlist = new List<ChatMessageModel>();
            var contentList = await _chatContentRep.GetListAsync(x => list.Select(x => x.ContentId).Contains(x.Id));
            foreach (var item in list)
            {
                var msg = item.Adapt<ChatMessageModel>();
                msg.IsNewMessage = false;
                msg.OneSelf = msg.SenderId == _currentUser.UserId ? true : false;

                var content = contentList.FirstOrDefault(x => x.Id == item.ContentId);
                if (content != null)
                {
                    msg.MessageType = content.MessageType;
                    if (content.MessageType == MessageTypeEnum.Img)
                    {
                        msg.Content = _fileService.GetStreamUrl(Convert.ToInt64(content.Content));
                    }
                    else
                    {
                        msg.Content = content.Content;
                    }
                }
                rlist.Add(msg);
            }

            return (rlist, rlist.Count < takeCount ? false : true);
        }

        /// <summary>
        /// 查询未读消息
        /// </summary>
        /// <returns></returns>
        public async Task<List<ChatMessageModel>> GetChatMessageNoReadList()
        {
            var list = await _rep.GetListAsync(x => x.TouserId == _currentUser.UserId && x.ReadTime == null);

            var rlist = new List<ChatMessageModel>();
            var contentList = await _chatContentRep.GetListAsync(x => list.Select(x => x.ContentId).Contains(x.Id));
            foreach (var item in list)
            {
                var msg = item.Adapt<ChatMessageModel>();
                var content = contentList.FirstOrDefault(x => x.Id == item.ContentId);
                if (content != null)
                {
                    msg.MessageType = content.MessageType;
                    if (content.MessageType == MessageTypeEnum.Img)
                    {
                        msg.Content = _fileService.GetStreamUrl(Convert.ToInt64(content.Content));
                    }
                    else
                    {
                        msg.Content = content.Content;
                    }
                }
                rlist.Add(msg);
            }

            return rlist;
        }

        public async Task<bool> UpdateMsgReaded(long msgId)
        {
            var msg = await _rep.GetByIdAsync(msgId);
            if (msg != null)
            {
                msg.ReadTime = DateTime.Now;

                return await _rep.UpdateAsync(msg);
            }
            return false;
        }

        public async Task<bool> Create(ChatMessageModel message)
        {
            //消息分为发送者的消息和接收者的消息，分别存储，消息内容公用一条数据
            //消息内容
            var content = new ChatContent
            { 
                Id = SnowFlakeHelper.GetLongId(),
                PairID = message.PairID,
                MessageType = message.MessageType,
                Content = message.Content
            };
            //发送者的消息
            var senderMsg = new ChatMessage();
            message.Adapt(senderMsg);
            senderMsg.Id = SnowFlakeHelper.GetLongId();
            senderMsg.ContentId = content.Id;
            senderMsg.ReadTime = DateTime.Now;
            //接收者的消息
            var receiverChatUser = await _chatUserRep.GetFirstAsync(x => x.UserId == message.TouserId && x.TouserId == _currentUser.UserId);
            var receiverMsg = new ChatMessage();
            message.Adapt(receiverMsg);
            receiverMsg.Id = SnowFlakeHelper.GetLongId();
            receiverMsg.BelongId = receiverChatUser.Id;
            receiverMsg.ContentId = content.Id;

            content.InsertExtraEntity.Add(senderMsg);
            content.InsertExtraEntity.Add(receiverMsg);

            return await content.InsertAsync();
        }

        public async Task<ObjectRet<SendChatInfoRet>> SendChatCheck(long touserId, int msgCount)
        {
            var ret = new ObjectRet<SendChatInfoRet>();
            var friend = await _chatFriendRep.GetFirstAsync(x => x.FriendUserId == _currentUser.UserId && x.UserId == touserId);
            if(friend != null)
            {
                ret.Success = true;
                var chatUser = await _chatUserRep.GetFirstAsync(x => x.MainId == friend.Id);
                if (chatUser == null) 
                {
                    //如果对方将自己的聊天删除，这里重新添加
                    chatUser = new ChatUser
                    {
                        Id = SnowFlakeHelper.GetLongId(),
                        MainId = friend.Id,
                        UserId = friend.FriendUserId,
                        NickName = friend.FriendNickName,
                        TouserId = _currentUser.UserId,
                        ToNickName = _currentUser.NickName,
                        LastTime = DateTime.Now,
                        PairID = friend.PairID,
                        IsHide = true,
                    };
                    ret.Success = await chatUser.InsertAsync();
                }
                else
                {
                    if (chatUser.IsHide)
                    {
                        //如果对方将自己的聊天隐藏，这里改为显示
                        chatUser.IsHide = !chatUser.IsHide;
                        ret.Success = await chatUser.UpdateAsync();
                    }
                }

                var msgIdList = new List<long>();
                for (int i = 0; i < msgCount; i++)
                {
                    msgIdList.Add(SnowFlakeHelper.GetLongId());
                }

                ret.Data = new SendChatInfoRet
                {
                    MsgIdList = msgIdList,
                    TimeStamp = DateTime.Now.Ticks,
                    SendTime = DateTime.Now
                };
            }
            else
            {
                ret.Success = false;
                ret.Message = "对方还未添加你为好友";
            }
            return ret;
        }
    }
}
